package com.xc.auth.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @description 安全管理配置
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    // AuthenticationManager 通常用于验证用户名和密码，但它也可以根据特定的需求进行自定义身份验证，例如使用令牌、证书等。
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    // 配置用户信息服务
//    @Bean
//    public UserDetailsService userDetailsService() {
//        // 这里配置用户信息,这里暂时使用这种方式将用户存储在内存中
//        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//        manager.createUser(User.withUsername("magic").password("magic").authorities("p1").build());
//        manager.createUser(User.withUsername("tommy").password("tommy").authorities("p2").build());
//        return manager;
//    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        //密码为明文方式
//        return NoOpPasswordEncoder.getInstance();
        return new BCryptPasswordEncoder();
    }

    //配置安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/r/**").authenticated()//访问/r开始的请求需要认证通过
                .anyRequest().permitAll()//其它请求全部放行
                .and()
                .formLogin().successForwardUrl("/login-success");//登录成功跳转到/login-success
    }

    // 生成密码：加密命名密码测试方法
    public static void main(String[] args) {
        String password = "magic";
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        for (int i = 0; i < 6; i++) {
            // 生成密码 每个计算出的Hash值都不一样
            String hashPass = passwordEncoder.encode(password);
            System.out.println(hashPass);
            // 校验密码 虽然每次计算的密码Hash值不一样但是校验是通过的
            // 参数1是输入的明文 ，参数2是正确密码加密后的串
            // matches(CharSequence rawPassword, String encodedPassword)
            boolean matches = passwordEncoder.matches(password, hashPass);
            System.out.println(matches);
        }
        boolean matches = passwordEncoder.matches("200", "$2a$10$vOvwuph7ltp9FrjG4ygrCeqAZALrDHaCDE3nmHKTc/C1vXpd4D7S2");
        System.out.println(matches);
    }
}
